#define LOG_NDEBUG 0
#define LOG_TAG "HLS_Tools"
//#include <utils/Log.h>

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <dirent.h>

#include "Tools.h"
#include "curl/curl.h"
#include "easyLog.h"

bool CTools::isCanceled = false;

void CTools::string_replace(string& strBig, const string& strSrc,
		const string& strDst) {
	string::size_type pos = 0;
	string::size_type srclen = strSrc.size();
	string::size_type dstlen = strDst.size();

	while ((pos = strBig.find(strSrc, pos)) != string::npos) {
		strBig.replace(pos, srclen, strDst);
		pos = dstlen;
	}
}

long int CTools::HttpDownloadSync(const char* pszUrl, const char* pszParam,
		MemoryStruct* chunk, char* pszLastURL, long * httpretcode) {
	long lRet = -1;
	if (httpretcode != NULL) {
		*httpretcode = 200;
	}

	if (!pszUrl || !chunk) {
		DEBUG_("pszUrl == null || chunk == null\n");
		return -1;
	}
	CURL *curl = NULL;
	CURLcode res;
	long retcode = 0;
	curl = curl_easy_init();
	if (curl) {
		curl_easy_setopt(curl, CURLOPT_URL, pszUrl);
		if (pszParam) {
			curl_easy_setopt(curl, CURLOPT_POSTFIELDS, pszParam);
		}
		chunk->size = 0;
		chunk->data = NULL;
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) chunk);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, chunkdata_callback);
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
		/* NOTE: It must be set, otherwise it will crash when timeout */curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
		//			}
		/* Here, should be not blocked until completed transfer */
		res = curl_easy_perform(curl);
//		DEBUG_("curl_easy_perform return value is %d \n", res);
		if (CURLE_OK != res) {
			DEBUG_("Curl told us error %d \n", res);
			if (httpretcode != NULL) {
				*httpretcode = res;
			}
		}
		else {
			res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &retcode);
			//DEBUG_("curl_easy_getinfo, res = %d, retcode=%d\n", res, retcode);
			if (httpretcode != NULL) {
				*httpretcode = retcode;
			}
			if ((res == CURLE_OK) && retcode == 200) {
				lRet = 0;
			}

			if (pszLastURL != NULL) {
				//				memset(pszLastURL,0,strlen(pszLastURL));
				//				char* pTmp = NULL;
				//				res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &pTmp);
				//				INFO_("(%ld) last url: %s", res, pTmp);
				//				strcpy(pszLastURL, pTmp);
			}
		}
		curl_easy_cleanup(curl);
	}
	if (CURLE_OK != res) {
		lRet = -1;
		ERR_("HttpDownloadSync ret = [%ld] url = [%s]\n", lRet, pszUrl);
	}
	return lRet;
}


size_t CTools::chunkdata_callback(void* ptr, size_t size, size_t nmemb,
		void* data) {
	if (isCanceled) {
		DEBUG_("Download is canceled\n");
		isCanceled = false;
//		return size * nmemb;
		return 0;
	}

	size_t realsize = size * nmemb;
	MemoryStruct* mem = NULL;

	if (realsize <= 0) return 0;
	mem = (MemoryStruct *) data;

	if (mem->data == NULL) {
		mem->data = (char*) calloc(1, mem->size + realsize + 1);
	}
	else {
		mem->data = (char*) realloc(mem->data, mem->size + realsize + 1);
	}
	if (mem->data) {
		memcpy(&(mem->data[mem->size]), ptr, realsize);
		mem->size += realsize;
		mem->data[mem->size] = 0;
	}
	return realsize;
}

void CTools::cancelDownload() {
	isCanceled = true;
}
void CTools::InitDownload() {
	isCanceled = false;
}

